package com.tmt.im.service.websocket;


import com.alibaba.fastjson2.JSONObject;
import com.tmt.im.service.websocket.message.SocketMessageResponse;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

/**
 * 服务端WebSocket(wss)组件
 *
 * @Description TODO
 * @Author wuyi
 * @Date 2024/8/13 13:46
 * @Version 1.0
 **/
@Slf4j
@Component
@ServerEndpoint(value = "/imx/v1/api/ws/Chat",
        configurator = WebsocketConfig.class,
        encoders = {ServerTextEncoder.class},
        decoders = {ServerBinaryDecoder.class})
public class ChatServerWebSocket {

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        if (session.getUserPrincipal() instanceof JwtAuthenticationToken token) {
            Long userId = token.getToken().getClaim("id");
            SessionContextManager.self.addSession(userId, session);
            log.info("------用户ID={}--------", userId);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        if (session.getUserPrincipal() instanceof JwtAuthenticationToken token) {
            Long userId = token.getToken().getClaim("id");
            SessionContextManager.self.removeSession(userId);
            log.info("------关闭用户连接(userId={})--------", userId);
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        if (session.getUserPrincipal() instanceof JwtAuthenticationToken token) {
            Long userId = token.getToken().getClaim("id");
            //更新最后通信时间。
            SessionContextManager.self.updateHeartBeatTime(userId);
            if (!"ping".equalsIgnoreCase(message)) {
                //判断是否需要关闭实时推送。
                SocketMessageResponse response = JSONObject.parseObject(message, SocketMessageResponse.class);
                if (response != null && !response.isCloseRealTimePush()) {
                    //关闭实时推送。
                    SessionContextManager.self.closeRealTimePush(userId);
                }
            } else {
                try {
                    //应答心跳
                    session.getAsyncRemote().sendText("pong");
                } catch (Exception ex) {
                }
            }
        }
    }

    /**
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {

    }

}
